<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Analytics Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Segoe UI", sans-serif;
background: #0f172a;
color: #e2e8f0;
}
.topbar {
background: #1e293b;
padding: 16px 32px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #334155;
}
.topbar h1 {
font-size: 1.4rem;
color: #a78bfa;
}
.cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
padding: 24px 32px;
}
.card {
background: #1e293b;
border-radius: 12px;
padding: 20px;
border: 1px solid #334155;
}
.card .label {
font-size: 0.8rem;
color: #94a3b8;
margin-bottom: 8px;
}
.card .value {
font-size: 2rem;
font-weight: 700;
color: #a78bfa;
}
.card .delta {
font-size: 0.8rem;
color: #34d399;
margin-top: 4px;
}
.charts {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 16px;
padding: 0 32px 24px;
}
.chart-box {
background: #1e293b;
border-radius: 12px;
padding: 20px;
border: 1px solid #334155;
}
.chart-box h3 {
font-size: 0.95rem;
color: #94a3b8;
margin-bottom: 16px;
}
.btn-row {
display: flex;
gap: 10px;
padding: 0 32px 24px;
}
.btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
cursor: pointer;
font-size: 0.85rem;
font-weight: 600;
transition: opacity 0.2s;
}
.btn:hover {
opacity: 0.85;
}
.btn-primary {
background: #7c3aed;
color: white;
}
.btn-success {
background: #059669;
color: white;
}
.btn-danger {
background: #dc2626;
color: white;
}
</style>
</head>
<body>
<div class="topbar">
<h1>๐ Analytics Dashboard</h1>
<span style="color:#94a3b8; font-size:0.85rem"
>Last updated: just now</span
>
</div>
<div class="cards">
<div class="card">
<div class="label">Total Revenue</div>
<div class="value" id="revenue">$84,200</div>
<div class="delta">โ 12.4% vs last month</div>
</div>
<div class="card">
<div class="label">Active Users</div>
<div class="value" id="users">3,821</div>
<div class="delta">โ 8.1% vs last month</div>
</div>
<div class="card">
<div class="label">Conversions</div>
<div class="value" id="conv">5.7%</div>
<div class="delta">โ 0.3% vs last month</div>
</div>
<div class="card">
<div class="label">Avg Session</div>
<div class="value">4m 12s</div>
<div class="delta">โ 0.5% vs last month</div>
</div>
</div>
<div class="btn-row">
<button class="btn btn-primary" onclick="refreshData()">
๐ Refresh Data
</button>
<button class="btn btn-success" onclick="exportCSV()">
โฌ Export CSV
</button>
<button class="btn btn-danger" onclick="resetData()">โ Reset</button>
</div>
<div class="charts">
<div class="chart-box">
<h3>Monthly Revenue</h3>
<canvas id="lineChart"></canvas>
</div>
<div class="chart-box">
<h3>Traffic Sources</h3>
<canvas id="doughnutChart"></canvas>
</div>
</div>
<script>
const lineCtx = document.getElementById("lineChart").getContext("2d");
const lineChart = new Chart(lineCtx, {
type: "line",
data: {
labels: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
],
datasets: [
{
label: "Revenue ($)",
data: [
42000, 47000, 51000, 46000, 58000, 63000, 70000, 67000, 74000,
79000, 82000, 84200,
],
borderColor: "#7c3aed",
backgroundColor: "rgba(124,58,237,0.1)",
tension: 0.4,
fill: true,
pointRadius: 4,
},
],
},
options: {
responsive: true,
plugins: { legend: { labels: { color: "#94a3b8" } } },
scales: {
x: { ticks: { color: "#94a3b8" }, grid: { color: "#1e293b" } },
y: { ticks: { color: "#94a3b8" }, grid: { color: "#334155" } },
},
},
});
const dCtx = document.getElementById("doughnutChart").getContext("2d");
new Chart(dCtx, {
type: "doughnut",
data: {
labels: ["Organic", "Paid", "Referral", "Social"],
datasets: [
{
data: [42, 28, 18, 12],
backgroundColor: ["#7c3aed", "#06b6d4", "#10b981", "#f59e0b"],
},
],
},
options: {
responsive: true,
plugins: { legend: { labels: { color: "#94a3b8" } } },
},
});
function refreshData() {
const newVal = (80000 + Math.random() * 10000).toFixed(0);
document.getElementById("revenue").textContent =
"$" + parseInt(newVal).toLocaleString();
document.getElementById("users").textContent = (
3500 + Math.floor(Math.random() * 500)
).toLocaleString();
lineChart.data.datasets[0].data = lineChart.data.datasets[0].data.map(
(v) => Math.max(40000, v + (Math.random() - 0.5) * 4000),
);
lineChart.update();
}
function exportCSV() {
const csv =
"Month,Revenue\n" +
[
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
.map((m, i) => `${m},${lineChart.data.datasets[0].data[i]}`)
.join("\n");
const a = document.createElement("a");
a.href = "data:text/csv," + encodeURIComponent(csv);
a.download = "dashboard.csv";
a.click();
}
function resetData() {
document.getElementById("revenue").textContent = "$84,200";
document.getElementById("users").textContent = "3,821";
}
</script>
</body>
</html>